
/**
* @1900-2100区间内的公历
* @charset UTF-8
* @Author  iRacer 杨
* @Time    2017-9-30
* @Version 1.0.1
*/

var VUE_CALENDAR = null;
var vue_component_calendar = {
    template: '<div class="calendar-div" style=""><input type="text" class="calendar-input" readonly v-on:focus="changeDate" v-on:click="noClickWindow($event)" v-bind:value="formatValue()" /><div class="calendar" v-bind:class="{show:calendarShow}"><div class="calendar-tools"><span class="calendar-prev" v-on:click="prev($event)">&lt;</span><span class="calendar-next" v-on:click="next($event)">&gt;</span><div class="calendar-info" v-on:click="changeYear"><div class="month"><div v-bind:style="{ top: -(this.month * 20) + \'px\' }" class="month-inner"><span v-for="m in months">{{m}}</span></div></div><div class="year">{{year}}</div></div></div><table cellpadding="5"><thead><tr><td v-for="week in weeks" class="week">{{week}}</td></tr></thead><tbody><tr v-for="(line, i) in days"><td v-for="(day, j) in line" v-bind:class="{selected:day.selected,disabled:day.disabled}" v-on:click="select(i, j, $event)"><span>{{ day.day }}</span></td></tr></tbody></table><div class="calendar-time"><input type="text" v-model="hour" v-on:click="timeFocus(0,$event)" maxlength="2" />:<input type="text" v-model="minute" v-on:click="timeFocus(1,$event)" maxlength="2" />:<input type="text" v-model="second" v-on:click="timeFocus(2,$event)" maxlength="2" /><a href="javascript:void(0)" v-on:click="minus">-</a><a href="javascript:void(0)" v-on:click="plus">+</a><a href="javascript:void(0)" class="calendar-btn" v-on:click="selectToday">今天</a><a href="javascript:void(0)" class="calendar-btn" v-on:click="selected">确定</a></div><div class="calendar-years" v-bind:class="{show:yearsShow}"><span v-for="y in years" v-on:click="selectYear(y,$event)" v-bind:class="{active:y==year}">{{y}}</span></div></div></div>',
    props: {
        format: {
            type: String,
            default: "yyyy-MM-dd" // yyyy-MM-dd hh:mm:ss
        },
        date: {
            type: String,
            default: ""
        },
        begin: {
            type: Array,
            default: function () {
                return []
            }
        },
        end: {
            type: Array,
            default: function () {
                return []
            }
        },
        weeks: {
            type: Array,
            default: function () {
                return window.navigator.language.toLowerCase() == "zh-cn" ? ['日', '一', '二', '三', '四', '五', '六'] : ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat']
            }
        },
        months: {
            type: Array,
            default: function () {
                return window.navigator.language.toLowerCase() == "zh-cn" ? ['一月', '二月', '三月', '四月', '五月', '六月', '七月', '八月', '九月', '十月', '十一月', '十二月'] : ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December']
            }
        },
        column: {
            type: String,
            default: ""
        }
    },
    data() {
        return {
            hour: "00",
            minute: "00",
            second: "00",

            calendarShow: false,
            yearsShow: false,
            year: 0,
            month: 0,
            day: 0,
            begin: [],
            end: [],
            today: [],
            value: ["2018","09","03"],
            days: [],
            years: [],
            weeks: ['日', '一', '二', '三', '四', '五', '六'],
            months: ['一月', '二月', '三月', '四月', '五月', '六月', '七月', '八月', '九月', '十月', '十一月', '十二月'],

            focusType: -1
        }
    },
    mounted () {
        this.init();
    },
    methods: {
        init() {

            // 没有默认值
            let now = new Date();
            this.year = now.getFullYear();
            this.month = now.getMonth();
            this.day = now.getDate();
            this.hour = 0;
            this.minute = 0;
            this.second = 0;

            if (this.date.length > 0) {
                this.value = (this.date.replace(' ', '-').replace(':', '-').replace(':', '-')).split('-');
                this.year = parseInt(this.value[0])
                this.month = parseInt(this.value[1]) - 1
                this.day = parseInt(this.value[2])
                if (this.value.length > 3) { this.hour = this.value[3] }
                if (this.value.length > 4) { this.minute = this.value[4] }
                if (this.value.length > 5) { this.second = this.value[5] }
            }
            this.selected();
            this.render(this.year, this.month);
            var cal = this;
            window.onclick = function () {
                cal.calendarShow = false;
            }

            if (VUE_CALENDAR) {
                VUE_CALENDAR.calendarShow = false;
                VUE_CALENDAR.focusType = -1;
            }
            VUE_CALENDAR = this;
        },
        formatValue () {
            if (this.value.length == 6) {
                return this.format.replace('yyyy', this.value[0]).replace('MM', this.value[1]).replace('dd', this.value[2]).replace('hh', this.value[3]).replace('mm', this.value[4]).replace('ss', this.value[5]); // "yyyy-MM-dd hh:mm:ss"
            }
            return "";
        },
        // 渲染日期
        render (y, m) {
            let firstDayOfMonth = new Date(y, m, 1).getDay()         //当月第一天
            let lastDateOfMonth = new Date(y, m + 1, 0).getDate()    //当月最后一天
            let lastDayOfLastMonth = new Date(y, m, 0).getDate()     //最后一月的最后一天
            this.year = y
            let seletSplit = this.value
            let i, line = 0, temp = [], nextMonthPushDays = 1
            for (i = 1; i <= lastDateOfMonth; i++) {
                let day = new Date(y, m, i).getDay() // 返回星期几（0～6）
                // 第一行
                if (day == 0) {
                    temp[line] = []
                } else if (i == 1) {
                    temp[line] = []
                    let k = lastDayOfLastMonth - firstDayOfMonth + 1
                    for (; k <= lastDayOfLastMonth;) {
                        temp[line].push({ year: this.computedPrevYear(), month: this.computedPrevMonth(false), day: k, disabled: false })
                        k++;
                    }
                }

                // console.log(this.lunar(this.year,this.month,i));
                // 单选模式
                let chk = new Date()
                let chkY = chk.getFullYear()
                let chkM = chk.getMonth()

                // 匹配上次选中的日期
                if (parseInt(seletSplit[0]) == this.year && parseInt(seletSplit[1]) - 1 == this.month && parseInt(seletSplit[2]) == i) {
                    // console.log("匹配上次选中的日期",lunarYear,lunarMonth,lunarValue,lunarInfo)
                    temp[line].push({ year: this.year, month: this.month, day: i, selected: true })
                    this.today = [line, temp[line].length - 1]
                }
                    // 没有默认值的时候显示选中今天日期
                else if (chkY == this.year && chkM == this.month && i == this.day && this.value == "") {

                    // console.log("今天",lunarYear,lunarMonth,lunarValue,lunarInfo)
                    temp[line].push({ year: this.year, month: this.month, day: i, selected: true })
                    this.today = [line, temp[line].length - 1]
                } else {
                    // 普通日期
                    // console.log("设置可选范围",i,lunarYear,lunarMonth,lunarValue,lunarInfo)
                    let options = { year: this.year, month: this.month, day: i, selected: false }
                    if (this.begin.length > 0) {
                        let beginTime = Number(new Date(parseInt(this.begin[0]), parseInt(this.begin[1]) - 1, parseInt(this.begin[2])))
                        if (beginTime > Number(new Date(this.year, this.month, i))) options.disabled = true
                    }
                    if (this.end.length > 0) {
                        let endTime = Number(new Date(parseInt(this.end[0]), parseInt(this.end[1]) - 1, parseInt(this.end[2])))
                        if (endTime < Number(new Date(this.year, this.month, i))) options.disabled = true
                    }
                    temp[line].push(options)
                }
                // 最后一行
                if (day == 6 && line < 4) {
                    line++
                } else if (i == lastDateOfMonth) {
                    // line++
                    let k = 1
                    for (let d = day; d < 6; d++) {
                        // console.log(this.computedNextYear()+"-"+this.computedNextMonth(true)+"-"+k)
                        temp[line].push({ year: this.computedNextYear(), month: this.computedNextMonth(false), day: k, disabled: false })
                        k++
                    }
                    nextMonthPushDays = k
                }
            } //end for

            // console.log(this.year+"/"+this.month+"/"+this.day+":"+line)
            // 补充第六行让视觉稳定
            if (line < 5 && nextMonthPushDays > 0) {
                line++
                temp[line] = []
                for (let d = nextMonthPushDays; d <= nextMonthPushDays + 6; d++) {
                    temp[line].push({ year: this.computedNextYear(), month: this.computedNextMonth(false), day: d, disabled: false });
                }
            }
            this.days = temp
        },
        computedPrevYear() {
            let value = this.year
            if (this.month - 1 < 0) {
                value--
            }
            return value
        },
        computedPrevMonth(isString) {
            let value = this.month
            if (this.month - 1 < 0) {
                value = 11
            } else {
                value--
            }
            // 用于显示目的（一般月份是从0开始的）
            if (isString) {
                return value + 1
            }
            return value
        },
        computedNextYear() {
            let value = this.year
            if (this.month + 1 > 11) {
                value++
            }
            return value
        },
        computedNextMonth(isString) {
            let value = this.month
            if (this.month + 1 > 11) {
                value = 0
            } else {
                value++
            }
            // 用于显示目的（一般月份是从0开始的）
            if (isString) {
                return value + 1
            }
            return value
        },
        // 上月
        prev(e) {
            e.stopPropagation()
            if (this.month == 0) {
                this.month = 11
                this.year = parseInt(this.year) - 1
            } else {
                this.month = parseInt(this.month) - 1
            }
            this.render(this.year, this.month)
        },
        //  下月
        next(e) {
            e.stopPropagation()
            if (this.month == 11) {
                this.month = 0
                this.year = parseInt(this.year) + 1
            } else {
                this.month = parseInt(this.month) + 1
            }
            this.render(this.year, this.month)
        },
        noClickWindow(e) {
            if (e != undefined) { e.stopPropagation(); }
        },
        changeDate(e) {
            if (e != undefined) { e.stopPropagation(); }
            if (this.calendarShow) {
                this.calendarShow = false
                return false
            }
            this.init();
            this.calendarShow = true
        },
        selectYear(value, e) {
            if (e != undefined) { e.stopPropagation(); }
            this.yearsShow = false
            this.year = value
            this.render(this.year, this.month)
        },
        changeYear(e) {
            e.stopPropagation()
            if (this.yearsShow) {
                this.yearsShow = false
                return false
            }
            this.yearsShow = true
            this.years = [];
            for (let i = this.year - 10; i < this.year + 10; i++) {
                this.years.push(i)
            }
        },
        selectToday () {
            let now = new Date();
            this.year = now.getFullYear();
            this.month = now.getMonth();
            this.day = now.getDate();
            this.hour = this.value[3];
            this.minute = this.value[4];
            this.second = this.value[5];
            this.calendarShow = false;
            this.focusType = -1;
            this.selected();
        },
        // 选中日期
        select(k1, k2, e) {
            if (e != undefined) e.stopPropagation();
            // 取消上次选中
            if (this.today.length > 0) {
                this.days.forEach(v=> {
                    v.forEach(vv=> {
                        vv.selected = false
                    })
                })
            }
            // 设置当前选中天
            this.days[k1][k2].selected = true
            this.today = [k1, k2]
            this.calendarShow = false
            this.focusType = -1;
            this.year = this.days[k1][k2].year
            this.month = this.days[k1][k2].month
            this.day = this.days[k1][k2].day
            this.selected();
        },
        // 确定
        selected(e) {
            if (e != undefined) { e.stopPropagation(); this.calendarShow = false; this.focusType = -1; }
            this.value = [this.year, this.zeroPad(this.month + 1), this.zeroPad(this.day), this.zeroPadTime(this.hour, 23), this.zeroPadTime(this.minute, 59), this.zeroPadTime(this.second, 59)];


            this.hour = this.value[3];
            this.minute = this.value[4];
            this.second = this.value[5];
            var _calendar = this;
            this.$emit('select', this.formatValue(), this.column, this.value, function (_value) {
                _calendar.value = [_value[0], _calendar.zeroPadTime(_value[1], 12), _calendar.zeroPadTime(_value[2], 31), _calendar.zeroPadTime(_value[3], 23), _calendar.zeroPadTime(_value[4], 59), _calendar.zeroPadTime(_value[5], 59)];
            });

            
        },
        plus (e) {
            if (e != undefined) { e.stopPropagation(); }
            if (this.focusType === 0) {
                this.hour = parseInt(this.hour) + 1;
                if (this.hour > 23) { this.hour = 23; }
            } else if (this.focusType === 1) {
                this.minute = parseInt(this.minute) + 1;
                if (this.minute > 59) { this.minute = 59; }
            } else if (this.focusType === 2) {
                this.second = parseInt(this.second) + 1;
                if (this.minute > 59) { this.minute = 59; }
            }
        },
        minus (e) {
            if (e != undefined) { e.stopPropagation(); }
            if (this.focusType === 0) {
                this.hour = parseInt(this.hour) - 1;
                if (this.hour < 0) { this.hour = 0;}
            } else if (this.focusType === 1) {
                this.minute = parseInt(this.minute) - 1;
                if (this.minute < 0) { this.minute = 0; }
            } else if (this.focusType === 2) {
                this.second = parseInt(this.second) - 1;
                if (this.second < 0) { this.second = 0; }
            }
        },
        timeFocus (focusType, e) {
            if (e != undefined) { e.stopPropagation(); }
            this.focusType = focusType;
        },
        // 日期补零
        zeroPad(n) {
            return String(n < 10 ? '0' + n : n)
        },
        // 时间补零
        zeroPadTime(n, max) {
            if (n === undefined || n === null || n === '' || isNaN(n)) {
                // 空格， null, undefined 非数值
                n = 0;
            } else {
                // 数值非法 0~max
                n = parseInt(n);
                if (n < 0) { n = 0; } else if (n > max) { n = max; }
            }
            // 时间补零
            return this.zeroPad(n);
        }
    }
};
Vue.component('calendar', vue_component_calendar);


Vue.component('calendar2', {
    template: '<div style="display:inline;"><calendar v-on:select="change1" v-bind:format="format" v-bind:date="date1"></calendar> - <calendar v-on:select="change2" v-bind:format="format" v-bind:date="date2"></calendar></div>',
    props: {
        format: { type: String, default: "yyyy-MM-dd hh:mm:ss" }, // yyyy-MM-dd
        date1: { type: String, default: "" },
        date2: { type: String, default: "" },
    },
    data () {
        return {};
    },
    components: {
        'calendar': vue_component_calendar,
    },
    methods: {
        change1 (date, col, value, callback) {

            if (date > this.date2)
            {
                callback((this.date1.replace(' ', '-').replace(':', '-').replace(':', '-')).split('-'));
                return false;
            }

            this.date1 = date;
            this.$emit('select', this.date1, this.date2);
        },
        change2 (date, col, value, callback) {
            if (this.date1 > date) {
                callback((this.date2.replace(' ', '-').replace(':', '-').replace(':', '-')).split('-'));
                return false;
            }
            this.date2 = date;
            this.$emit('select', this.date1, this.date2);
        }
    }
});